<?php

namespace Proyecto\MainBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Proyecto\MainBundle\Entity\Elemento;
use Proyecto\MainBundle\Form\ElementoType;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Elemento controller.
 *
 * @Route("/admin/elemento")
 */
class ElementoController extends Controller
{
    protected $container;
    
    public function __construct(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
    
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();
        
        $entities = $em->getRepository('ProyectoMainBundle:Elemento')->findAll();

        return array(
            'entities' => $entities,
        );
    }

    /**
     * Creates a new Elemento entity.
     *
     * @Route("/", name="elemento_create")
     * @Method("POST")
     * @Template("ProyectoMainBundle:Plantilla:load.html.twig")
     */
    public function createAction(Request $request)
    {
        $resultado = '';    
        $entity  = new Elemento();
        $form = $this->createForm(new ElementoType(), $entity);
        $form->bind($request);
        if ($form->isValid()){
          $em = $this->getDoctrine()->getManager();
          
          $entity->setOrden($this->proximoOrden($entity->getPlantilla()));
          $em->persist($entity);
          $em->flush();
          $resultado='El elemento se cargó a la plantilla con éxito';
        }
        
        return array(
            'entity' => $entity,
            'form'   => $form->createView(),
            'resultado' => $resultado,
            
        );
    
    }

    /**
     * Displays a form to create a new Elemento entity.
     *
     * @Route("/new", name="elemento_new")
     * @Method("GET")
     * @Template("ProyectoMainBundle:Plantilla:load.html.twig")
     */
    public function newAction()
    {
        $entity = new Elemento();
        $form   = $this->createForm(new ElementoType(), $entity);
        return array(
            'entity' => $entity,
            'form'   => $form->createView(),
        );
    }

    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ProyectoMainBundle:Elemento')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Elemento entity.');
        }

        $deleteForm = $this->createDeleteForm($id);

        return array(
            'entity'      => $entity,
            'delete_form' => $deleteForm->createView(),
        );
    }

    public function editAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ProyectoMainBundle:Elemento')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Elemento entity.');
        }

        $editForm = $this->createForm(new ElementoType(), $entity);
        $deleteForm = $this->createDeleteForm($id);

        return array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        );
    }

    
    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('ProyectoMainBundle:Elemento')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Elemento entity.');
        }

        $deleteForm = $this->createDeleteForm($id);
        $editForm = $this->createForm(new ElementoType(), $entity);
        $editForm->bind($request);

        if ($editForm->isValid()) {
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl('elemento_edit', array('id' => $id)));
        }

        return array(
            'entity'      => $entity,
            'edit_form'   => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        );
    }

    /**
     * Deletes a Elemento entity.
     *
     * @Route("/{id}", name="elemento_delete")
     * @Method("DELETE")
     */
    public function deleteAction(Request $request, $id)
    {
        $form = $this->createDeleteForm($id);
        $form->bind($request);
        
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $entity = $em->getRepository('ProyectoMainBundle:Elemento')->find($id);
            $idplantilla = $entity->getPlantilla()->getId();
            if (!$entity) {
                throw $this->createNotFoundException('Unable to find Elemento entity.');
            }
            $this->actualizarOrdenBorrado($entity->getOrden(),$idplantilla);
            $em->remove($entity);
            $em->flush();
            return $this->redirect($this->generateUrl('plantilla_modificar', array('id' => $idplantilla)));
        }
        
    }

    /**
     * Creates a form to delete a Elemento entity by id.
     *
     * @param mixed $id The entity id
     *
     * @return Symfony\Component\Form\Form The form
     */
    private function createDeleteForm($id)
    {
        return $this->createFormBuilder(array('id' => $id))
            ->add('id', 'hidden')
            ->getForm()
        ;
    }
    
    private function proximoOrden($idplantilla){
        $em=$this->getDoctrine()->getManager();
        $query = $em->createQuery(
                       'SELECT e.orden
                        FROM ProyectoMainBundle:Elemento e
                        WHERE e.plantilla = :plantilla
                        ORDER BY e.orden DESC'
                        )->setParameter('plantilla', $idplantilla);
          $query->setMaxResults(1);
          $orden = $query->getSingleResult();
          if ($orden['orden']){
              $orden['orden']++;
          }
          else{
              $orden['orden']=0;
          }
          return $orden['orden'];
    }
    
    /**
     * Retorna una matriz de formularios para editar y eliminar los elementos de una plantilla
     *
     * @param integer $id El id de una plantilla
     * @return Una matriz de formularios de edición, eliminación y el id de los elementos
     */
    public function formsElementos($idplantilla){
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQuery(
                       'SELECT e
                        FROM ProyectoMainBundle:Elemento e
                        WHERE e.plantilla = :plantilla
                        ORDER BY e.orden ASC'
                        )->setParameter('plantilla', $idplantilla);
        $elementos = $query->getResult();
        $forms_elemento=array();
        $i=0;
        foreach ($elementos as $elemento){
            $i++;
            $forms_elemento[$i]=array();
            $forms_elemento[$i]['delete'] = $this->createDeleteForm($elemento->getId())->createView();
            $forms_elemento[$i]['edit']= $this->createForm(new ElementoType(), $elemento)->createView();
            $forms_elemento[$i]['id']=$elemento->getId();
            $forms_elemento[$i]['valor_real']=$this->valorReal($elemento->getId());
        }
        return $forms_elemento;
        
    }
    
    private function valorReal($idelemento){
        $em = $this->getDoctrine()->getManager();
        $elemento = $em->getRepository('ProyectoMainBundle:Elemento')->find($idelemento);
        switch ($elemento->getTipo()){
            case 'label':
                $valor= $elemento->getValor();
                break;
            case 'item': 
                $query = $em->createQuery(
                       'SELECT i.descripcion
                        FROM ProyectoMainBundle:Item i
                        WHERE i.id = :iditem'
                        )->setParameter('iditem', $elemento->getValor());
                $query->setMaxResults(1);
                $result = $query->getSingleResult();
                $valor = $result['descripcion'];
                break;
            case 'separador':
                $query = $em->createQuery(
                       'SELECT s.codigo
                        FROM ProyectoMainBundle:Separador s
                        WHERE s.id = :idseparador'
                        )->setParameter('idseparador', $elemento->getValor());
                $query->setMaxResults(1);
                $result = $query->getSingleResult();
                $valor = $result['codigo'];
                break;
                        
        }
        return $valor;
    }
    
    /**
     * Edits an existing Elemento entity.
     *
     * @Route("/{id}", name="elemento_update")
     * @Method("PUT")
     * @Template()
     */
    public function actualizarAction(Request $request, $id){
        $em = $this->getDoctrine()->getManager();
        $em->getConnection()->beginTransaction();
        try { 
            $entity = $em->getRepository('ProyectoMainBundle:Elemento')->find($id);

            if (!$entity) {
                throw $this->createNotFoundException('Unable to find Elemento entity.');
            }
            $orden_viejo = $entity->getOrden();
            $idplantilla=$entity->getPlantilla()->getId();
            $editForm = $this->createForm(new ElementoType(), $entity);
            $editForm->bind($request);
            if ($editForm->isValid()) {
                $orden_nuevo = $this->actualizarOrdenInsercion($orden_viejo,$entity->getOrden(),$idplantilla,$em);
                $query = $em->createQuery(
                                  'UPDATE ProyectoMainBundle:Elemento e
                                   SET e.orden = :orden, e.estilo = :estilo
                                   WHERE e.plantilla = :idplantilla and e.id = :idelemento ' 
                                  );
                $query->setParameter('orden', $orden_nuevo);
                $query->setParameter('estilo', $entity->getEstilo());
                $query->setParameter('idelemento', $id);
                $query->setParameter('idplantilla', $idplantilla);
                $query->execute();
                $resultado='La modificación se realizó con éxito';
            }
            else {
                $resultado='';
                $validator = $this->get('validator');
                $errors = $validator->validate($editForm);
                foreach ($errors as $error){
                    $resultado.=' '.$error->getMessage();
                }
            }
            $em->getConnection()->commit();

        }
        catch (Exception $e) {
            $em->getConnection()->rollback();
            $em->close();
            throw $e;
        }
        
        return $this->redirect($this->generateUrl('plantilla_modificar', array('id' => $idplantilla,'current_page' => $this->getRequest()->request->get('current_page',1),'errores' => $resultado)));
        
        
    }

        
    
    
    private function actualizarOrdenInsercion($orden_viejo,$orden_nuevo,$plantilla,$em){
	if ($orden_nuevo < 1){
            $orden_nuevo = 1;
        }
	$query = $em->createQuery("SELECT max(e.orden) as orden
                            FROM ProyectoMainBundle:Elemento e
                            WHERE e.plantilla = :idplantilla"
                        )->setParameter('idplantilla',$plantilla);
        $query->setMaxResults(1);
	$resultado=$query->getSingleResult();
        $max_orden=$resultado['orden'];
	if ($orden_nuevo>$max_orden){
	    $orden_nuevo=$max_orden;
	}
	if ($orden_viejo<$orden_nuevo){
            $query=$em->createQuery("UPDATE ProyectoMainBundle:Elemento e
                                      SET e.orden = e.orden-1
                                      WHERE e.plantilla = :idplantilla and e.orden between :orden_i and :orden_j");
            $query->setParameter('idplantilla',$plantilla);
            $query->setParameter('orden_i',$orden_viejo+1);
            $query->setParameter('orden_j',$orden_nuevo);
            $query->execute();
	}
	elseif ($orden_viejo>$orden_nuevo){
            $query=$em->createQuery("UPDATE ProyectoMainBundle:Elemento e
                                     SET e.orden = e.orden+1
                                     WHERE e.plantilla = :idplantilla and e.orden between :orden_i and :orden_j");
	    $query->setParameter('idplantilla',$plantilla);
            $query->setParameter('orden_i',$orden_nuevo);
            $query->setParameter('orden_j',$orden_viejo-1);
            $query->execute();
	}
        return $orden_nuevo;
    }
    
    private function actualizarOrdenBorrado($orden,$idplantilla){
        $em = $this->getDoctrine()->getManager();
	$query = $em->createQuery("UPDATE ProyectoMainBundle:Elemento e
                                   SET e.orden = e.orden-1
                                   WHERE e.orden > :orden and e.plantilla = :idplantilla");
        $query->setParameter('idplantilla',$idplantilla);
        $query->setParameter('orden',$orden);
        $query->execute();        
    }
    

}
